//go:build mage
// +build mage

package main

import (
	"fmt"
	"math/rand"
	"os"
	"os/exec"
	"path"
	"strconv"
	"strings"

	"github.com/blang/semver"
	"github.com/magefile/mage/sh"
	"github.com/toolkits/file"
	"gopkg.in/ini.v1"

	// mage:import
	build "github.com/grafana/grafana-plugin-sdk-go/build"
)

// Default configures the default target.
var Default = build.BuildAll

// TODO: Release release plugin
func Release() {
	return
	envvs := loadEnv(".env")
	_version := loadVersion("./version")
	ver, err := semver.Parse(_version)
	checkErr(err)
	if err != nil {
		return
	}
	_ = ver

	os.RemoveAll("./dist")
	// compile backend
	build.BuildAll()
	// package frontend
	checkErr(sh.RunV("npm", "run", "build"))

	// TODO: 替换dist中的version: error
	sedCmd := fmt.Sprintf("'sed -i \"\" \"s/\\\"version\\\": \\\"1.0.0\\\"/\\\"version\\\": \\\"%s\\\"/g\" %s", _version, "dist/plugin.json'")
	checkErr(sh.RunV("/bin/bash", "-c", sedCmd))
	_, err = exec.Command("/bin/bash", "-c", sedCmd).CombinedOutput()
	checkErr(err)

	// sign
	checkErr(sh.RunWithV(envvs, "npm", "run", "sign"))
	// comporess zip file
	pkgname := fmt.Sprintf("grafana-opengauss-plugin-dev-%s.zip", _version)
	pkgpath := path.Join("release", pkgname)
	checkAndCreate("release")
	checkErr(sh.RunWithV(envvs, "/bin/bash", "-c", fmt.Sprintf("cd ./dist && zip -r %s *", "../"+pkgpath)))
	// TODO: upload zip file to grafana
	// TODO: git commit bump version
}

// Release_dev release plugin to develop environment
func Release_dev() {
	envvs := loadEnv(".env")
	envvs["GRAFANA_OPENGAUSS_PLUGIN_ENV"] = "development"

	// package frontend
	checkErr(sh.RunV("npm", "run", "build"))
	// compile backend
	build.BuildAll()

	// random dev version
	var version string = strconv.Itoa(rand.Intn(1000))
	pkgname := fmt.Sprintf("grafana-opengauss-plugin-dev-%s.zip", version)
	pkgpath := path.Join("release", pkgname)
	checkAndCreate("release")
	// compress to zip file
	checkErr(sh.RunWithV(envvs, "/bin/bash", "-c", fmt.Sprintf("cd ./dist && zip -r %s *", "../"+pkgpath)))

	// cp plugin to GRAFANA_PLUGIN_DIR
	pluginDir := envvs["GRAFANA_PLUGIN_DIR"]
	if pluginDir != "" {
		if convert2bool(envvs["CLEAR_ALL_PLUGIN"]) {
			os.RemoveAll(pluginDir)
			checkAndCreate(pluginDir)
		}
		checkErr(sh.RunV("cp", pkgpath, pluginDir))
		target := path.Join(pluginDir, pkgname)
		checkErr(sh.RunV("unzip", "-o", target, "-d", path.Join(pluginDir, strings.TrimRight(pkgname, path.Ext(pkgname)))))
	}
}

func checkAndCreate(dir string) {
	if file.IsExist(dir) {
		return
	}
	if err := exec.Command("mkdir", "-p", dir).Run(); err != nil {
		fmt.Println(err)
	}
}

func checkErr(err error) {
	if err != nil {
		fmt.Println("err = ", err)
	}
}

func loadEnv(fn string) (envvs map[string]string) {
	envvs = make(map[string]string)
	conf, err := ini.Load(fn)
	if err != nil {
		return
	}
	secs := conf.Sections()
	for _, sec := range secs {
		ptr := conf.Section(sec.Name())
		keys := ptr.Keys()
		for _, key := range keys {
			key.Name()
			vv, err := sec.GetKey(key.Name())
			if err != nil {
				continue
			}
			envvs[key.Name()] = vv.String()
		}
	}

	return
}

func convert2bool(val string) bool {
	val = strings.TrimSpace(val)
	val = strings.ToLower(val)
	switch val {
	case "y", "yes", "true", "t", "1":
		return true
	default:
		return false
	}
}

func loadVersion(fn string) string {
	content, err := os.ReadFile(fn)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	return string(content)
}
